クラスメソッドのReact事情大公開スペシャル#6 -「React Contextの状態管理について考える」というテーマで登壇しました #cm_react
はじめに
コンサル部の神野です!
先日、「クラスメソッドのReact事情大公開スペシャル#6」というイベントにて、「React Contextの状態管理について考える」というテーマで登壇しました。
登壇資料
登壇資料はこちらです。
対象・目的
今回はReact初心者 ~ 中級者でReact Contextを使っていて課題を感じている方に向けて、登壇させていただきました。
今回の登壇を通じてReact Contextの設計を見直すきっかけになったら何よりです!!
Reactの状態管理とは
まずはReactの状態管理について、お話ししました。
useState
を使ってそれぞれのコンポーネントで状態管理を行い、親子のコンポーネントで状態を共有する場合はprops
を経由しますが、バケツリレーが発生し可読性やパフォーマンス面など意識することが多々あります。
useState
useStateでの親子間状態共有
こういった課題を解消するために、下記選択が考えられます。
その中でもReact Contextは標準機能であるため、学習コストも低く採用してみようとなる可能性が高いと思います。
ただ、採用したはいいものの使っていく中で課題も発生してくるかと思います。
React Contextの課題
そもそもReact Contextの利用イメージについてみていきましょう。バケツリレーの構造とは何が異なるのでしょうか?
React Contextの利用イメージ
Provider
を経由してそれぞれのコンポーネントが状態を利用するイメージです。
バケツリレーは解消されて便利な反面、肥大化してくると下記の課題も現れてきます。
Context Hell
React Contextは状態を管理するのに便利な機能ですが、安易な使用は「Context Hell」(もしくはProvider Tower)と呼ばれる問題を引き起こす可能性があり、複数のContextが入り組むことで依存関係が複雑化し、コードの保守性が著しく低下するケースがあります。
肥大化するValue
React Contextのvalueに多くの状態や更新関数を含めすぎると、コンポーネントの再レンダリングが不必要に発生し、パフォーマンスに影響を与える可能性があります。また多くのValueを提供すると可読性や責任分解点も不明瞭となる可能性があります。
どちらにせよ、しっかりと考えて設計する必要があり、安易に使っていると肥大化して可読性やパフォーマンスが落ちていく可能性があります。
そういった中で上記問題にどう対応していくのがいいでしょうか?
React Contextの設計
対応方針は下記スライドを検討していきます。
設計を見直す、外部ライブラリを使用するなど考えられます。
設計の見直し
Provider
で提供しているスコープやそもそもグローバルで必要なStateなのか、再検討していきます。
何となく全体で使うためにグローバルで持たせている、大きなProvider
で全ての状態を管理していないか??を改めて確認して、見直しを図っていきます。
外部ライブラリの使用検討
React Contextが担っている役割を外部ライブラリに代替できないか検討しよりスリムにできないか検討します。
- 外部データソースからフェッチしている情報の保存はReact Contextではなく、SWR/Tanstack Queryなどのライブラリを使用
- 全体の状態管理は軽量なJotaiなどを使用
まとめ
上記の改善案をまとめると下記スライドの通りとなります。
まずは現時点でReact Contextが肥大化した使い方をしていないか(無闇にグローバルなStateとしていないか、Providerのスコープは適切かどうかなど)、React Contextよりも適切な外部ライブラリは存在しないかを検討していくことで見直しを図れるかと思います。
おわりに
今回話した内容はいかがでしたでしょうか!
今回の内容が正解といったわけでもなく、React Contextの状態管理について考えるのは難しいですが、その中でも最適解を見つけてよりよい実装にしていく参考になったら幸いです!
最後までご覧いただきありがとうございましたー!!